<!-- <!DOCTYPE html> -->
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    <title>脱离引力</title>
    <style type="text/css">
    @font-face{
      font-family: game;
      src: url('./font/HelveticaNeue-UltraLigExt.otf');
    }
    *{
      user-select: none;
    }
      html,body{
        width: 100vw;
        height:100vh;
        overflow: hidden;
        margin:0;
        background-color:rgb(0, 0, 0) !important;
        
      }
      #cover_c{
        width: 100vw;
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .tip{
        color: white;
        text-align: center;
        white-space: nowrap;
      }
      #cover{
        width:200px;
        display: block;
        /* background: white; */
      }
      canvas{
        /*border:red solid 1px;*/
        background:white;
      }
      #endPage{
        background:black;
      }
      #point_c{
        width: 100%;
        height: 100px;
        position: absolute;
        top: 0;
        bottom:0;
        margin: auto;
        display:none;
      }
      #point_c p{
        color: white;
        text-align: center;
        font-family:game;
      }
      #Refresh{
        border-radius: 10px;
        width: 200px;
        height: 50px;
        color: black;
        font-size: 16px;
        outline: none;
        background:white;
        border:none;
        display: block;
        margin: 0 auto;
      }
      #Refresh:active{
        font-size: 15px;
      }
      #AddPoint{
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 150px;
        width: 100%;
        height: 100%;
        top: 0;
        margin: 0;
        text-align: center;
        opacity: 0.1;
        font-family:game;
        font-weight: 100;
        user-select: none;
      }
    </style>
  </head>
  <body>
    <div id="cover_c">
      <div id="cover">
        <img id="cover" src="./icon.png" alt="" />
        <p class="tip">点击任意位置开始</p>
      </div>
    </div>
    <canvas id="canvas"></canvas>
    <div id="point_c">
      <p id="point">你穿越了167颗星球</p>
       <input type="button" id="Refresh" value="重玩" />
    </div>
    <h1 id="AddPoint">0</h1>
  </body>
  <script type="text/javascript">
    $G&&$G.onCreated(function(){
      $G.removeViewTop()
      $G.setScreenOrientation({
        orientation:"portrait"
      })
    })
    var canvas=document.getElementById("canvas");//获取画布对象
    var context=canvas.getContext("2d");//产生上下文对象
    var cover=document.getElementById("cover");//获取封面对象
    var cover_c=document.getElementById("cover_c");//获取封面容器对象
    var point_c=document.getElementById("point_c");//存分数的容器
    var pointText=document.getElementById("point");//显示分数
    var AddPoint=document.getElementById("AddPoint");
    var dpr = window.devicePixelRatio || 1;
    var winW=window.screen.width * dpr;//获取窗口像素
    var winH=window.screen.height * dpr;//获取窗口像素
    var count=5;//障碍物的数量
    var AllXY=[];//用来存储所有障碍物的坐标
    var AllY=[];//用来保存Y轴的坐标
    var circleStop;//停止做圆周运动的清除id;
    var lineStop;//停止做直线运动的id;
    var moveDownIsStop=false;//该变量存储下移动画是否结束
    var linePathIsStop=true;//该变量存储直线运动是否结束
    var circlePathIsStop=false;//该变量存储圆周运动是否结束
    var point=0;//初始化的时候，设置分数为
    // var offsetBottom=parseInt(winH/count);//一次的下移量
    var barrier={//定义一个障碍物的通用属性
      r:30*dpr,//设置障碍物的半径为30
    }
    var Contant={//存储碰撞到障碍物时，障碍物的坐标
      x:-100,//获取碰撞障碍物的x坐标
      y:-100,//获取碰撞障碍物的y坐标
      startRadian:0,//保存圆周运动的开始位置
      result:null,//设置结构为0
    }
    var thisHub={//设置一个对象保存飞船距离最近的障碍坐标
      //当碰撞之后就变成碰撞到的那个障碍物的坐标
      //当点击离开障碍做直线运动的时候，保存的是离开的那个障碍物的坐标
      centerX:0,//设置初始化x轴为0
      centerY:0,//设置初始化y轴为0
    }
    var skyBoat={//定义一个飞船对象
      x:-100, // 飞船的x
      y:-100, // 飞船的y
      vx:1*dpr,//设置x坐标的加速度
      vy:1*dpr,//设置y坐标的加速度
      r:5*dpr,//设置飞船的半径
      color:"black",//设置颜色
    }
    if(winW<=320){//如果宽度小于等于320,设置为320，并且设置overflow为auto
      winW=320;
      document.body.style.overflow="auto";
    };
    if(winH<=400){//如果高度小于等于400,设置为400，并且设置overflow为auto
      winH=400;
      document.body.style.overflow="auto";
    }
   
    canvas.width=winW;//设置绘图的宽
    canvas.height=winH;//设置绘图的高
    canvas.style.width=winW/dpr+"px";//设置显示宽度
    canvas.style.height=winH/dpr+"px";//设置显示高度
    cover_c.onclick=function(){//当点击封面容器的时候执行函数体内的行为
      var width=parseInt(getStyle(cover).width);//获取图像的宽度
      var time=setInterval(function(){//做一个简单的过度动画
        width-=10;
        cover.style.width=width+'px';
        if(width<=0){
          clearInterval(time);
          // document.body.removeChild(cover_c);
          cover_c.style.display = "none"
          document.body.style.background="white";
          AddPoint.style.position="absolute";
        }
      },0);
    }//初始化界面，点击进入游戏界面
    AddPoint.addEventListener("touchend",function(){//兼容手机端
      console.log("touchstart")
        clearInterval(circleStop);
        circlePathIsStop=true;//设置圆周运动的状态为停止
        //直线动画停止
        //圆周动画正在进行
        //下移动画停止
        //以上条件都成立的时候才能执行直线运动
        if(linePathIsStop&&!moveDownIsStop&&circlePathIsStop){
            LinePath(thisHub.centerX,thisHub.centerY);//
        }
    });
    AddPoint.addEventListener("mousedown",function(){//pc端
      console.log("onmousedown")
        clearInterval(circleStop);
        circlePathIsStop=true;//设置圆周运动的状态为停止
        //直线动画停止
        //圆周动画正在进行
        //下移动画停止
        //以上条件都成立的时候才能执行直线运动
        if(linePathIsStop&&!moveDownIsStop&&circlePathIsStop){
            LinePath(thisHub.centerX,thisHub.centerY);//
        }
    });


    Refresh.onclick=function(){//重新玩游戏
      //  window.location=window.location;
      point_c.style.display = "none"
      AddPoint.style.display = "flex"
      // cover_c.style.display = "flex"
      
     
      AllXY=[];//用来存储所有障碍物的坐标
      AllY=[];//用来保存Y轴的坐标
      canvas.id="canvas"
      moveDownIsStop=false;//该变量存储下移动画是否结束
      linePathIsStop=true;//该变量存储直线运动是否结束
      circlePathIsStop=false;//该变量存储圆周运动是否结束
      point=0;//初始化的时候，设置分数为
      AddPoint.innerText=point;
      Contant={//存储碰撞到障碍物时，障碍物的坐标
        x:-100,//获取碰撞障碍物的x坐标
        y:-100,//获取碰撞障碍物的y坐标
        startRadian:0,//保存圆周运动的开始位置
        result:null,//设置结构为0
      }
      context.clearRect(0,0,canvas.width,canvas.height);
      init();//点击进去之后初始化图像界面
     

      drawCircle(skyBoat.x,skyBoat.y,skyBoat.r,'fill');//初始化飞船
      circlePath(AllXY[AllXY.length-2],AllXY[AllXY.length-1],skyBoat);//初始化做圆周运动
      
      // console.log("33434343")
      //  window.onload = function(){

      //  }
    }
    function init(){//初始化函数
     for (var i = 1; i <=count*2;i+=2){//循环生成障碍物
       var startX=getRandomX();//获取随机的x坐标
       var startY=parseInt((winH/(count*2))*i);//获取固定的y坐标
       drawCircle(startX,startY,barrier.r,'stroke');//绘制
       AllXY.push(startX,startY);//AllXY数组保存每一个障碍物的x和y坐标
       AllY.push(startY);
     }
    //  skyBoat.x = AllXY[0]-barrier.r;//默认的飞船X坐标是在第一个障碍物的圆周上，即是障碍物的x坐标减去半径
    //  skyBoat.y = AllXY[1]-barrier.r;//默认的飞船Y坐标是在第一个障碍物的圆周上，即是障碍物的y坐标减去半径
      skyBoat.x = -10
      skyBoat.y = -10

     thisHub.centerX=0
     thisHub.centerY=0

     Contant={//存储碰撞到障碍物时，障碍物的坐标
      x:-100,//获取碰撞障碍物的x坐标
      y:-100,//获取碰撞障碍物的y坐标
      startRadian:0,//保存圆周运动的开始位置
      result:null,//设置结构为0
    }
   };//初始化界面的星球障碍物
  
  
    
    init();//点击进去之后初始化图像界面
    drawCircle(skyBoat.x,skyBoat.y,skyBoat.r,'fill');//初始化飞船
    circlePath(AllXY[AllXY.length-2],AllXY[AllXY.length-1],skyBoat);//初始化做圆周运动
    context.globalAlpha=0.9//设置全局的透明值

    function getStyle(obj){//获取样式的一个方法
      var style=null;
      if(window.getComputedStyle){
        style=window.getComputedStyle(obj,null);//火狐谷歌支持
      }else{
        style=obj.currentStyle;//ie支持
      }
      return style;
    }
    function drawCircle(x,y,r,type){//绘制圆的一个方法
      context.beginPath();
      context.arc(x,y,r,0,2*Math.PI);
      switch(type){
        case "stroke":
          context.strokeStyle="rgba(0,0,0,1)";
          context.stroke();
        break;
        case "fill":
          context.fillStyle="black";
          context.fill();
        break;
        default:
        console.log("参数错误");
      }
      context.closePath();

    }
    function LinePath(centerX,centerY){//飞船直线运动的一个方法

      //传入的centerX指的是飞船没有碰撞到障碍物之前的那个障碍物的X坐标
      //传入的centerY指的是飞船没有碰撞到障碍物之前的那个障碍物的Y坐标
      var x3=parseFloat(skyBoat.x.toFixed(2));//将skyBoat.x的值暂时保存在x3中
      var y3=parseFloat(skyBoat.y.toFixed(2));//将skyBoat.x的值暂时保存在x3中
      var step = 1;
      linePathIsStop=false;//设置直线运动的状态为运动
      lineStop=setInterval(function(){
        if(step<10){
          step+=1
        }else{
          step-=1
        }
        if(step<=1)step=1

        context.clearRect(0,0,winW,winH);//清除上一个位置的绘制图像
        //判断运动坐标是从哪个象限开始触发，才能得出飞船的直线方向
        if(centerX<skyBoat.x&&centerY>skyBoat.y){
          // 第一象限
           y3-=step;
           y3=parseFloat(y3.toFixed(2));
           x3=getx3(skyBoat.x,skyBoat.y,centerX,centerY,y3);
        }
        if(centerX>skyBoat.x&&centerY>skyBoat.y){
          // 第二象限
           y3-=step;
           y3=parseFloat(y3.toFixed(2));
           x3=getx3(skyBoat.x,skyBoat.y,centerX,centerY,y3);
        }
        if(centerX>skyBoat.x&&centerY<skyBoat.y){
          // 第三象限
           x3-=step;
           x3=parseFloat(x3.toFixed(2));
           y3=gety3(skyBoat.x,skyBoat.y,centerX,centerY,x3);
        }
        if(centerX<skyBoat.x&&centerY<skyBoat.y){
          // 第四象限
           x3+=step;
           x3=parseFloat(x3.toFixed(2));
           y3=gety3(skyBoat.x,skyBoat.y,centerX,centerY,x3);
        }
        if(centerX==skyBoat.x){
          // 垂直于x)
            if(centerX>skyBoat.x){
              //向下移动
               y3+=step;
            }else{
              //向上移动
              y3-=step;
            }
           x3=skyBoat.x;
        }
        if(centerY==skyBoat.y){
          console.log("垂直于y轴");
            if(centerY>skyBoat.y){
              //向左移动
               x3-=step;
            }else{
              //向右移动
              x3+=step;
            }
           y3=skyBoat.y;
        }
        //以上的代码是使飞船做正确的直线运动
        if(x3<0||x3>=winW||y3<0||y3>=winH){//判断是否超过界限;
          canvas.id="endPage"
          //显示分数
          point_c.style.display="block";
          // document.body.removeChild(AddPoint);
          AddPoint.style.display = "none"
          pointText.innerText="你穿越了"+point+"颗星球";

          clearInterval(lineStop);
          linePathIsStop=true;
        }
        //以上代码是判断是都超过边界，超过边界就结束
        var r=isContact(AllXY,x3,y3)//返回一个对象,可以得出是否与障碍产生碰撞
        if(r){
          if(r.result===false){
            console.log("发生触碰");
            // AddPoint.innerText=point;
            skyBoat.x=parseFloat(x3);//发生碰撞时更新skyBoat的x坐标
            skyBoat.y=parseFloat(y3);//发生碰撞时更新skyBoat的y坐标
            clearInterval(lineStop);//如果发生碰撞，就停止直线运动
            linePathIsStop=true;//设置
            clearInterval(circleStop);//如果发生碰撞，就停止圆周运动
            circlePathIsStop=true;
            var br = barrier.r
            var c=getDistance(x3,y3,r.x,r.y-br);//算出c边的长
            var cosValue=((br*br)+(br*br)-(c*c))/(2*br*br);//算出c边对应的角度
            if(x3<r.x){//如果落点在圆心的左边，形成的角度是补角，要360-去补角才得出正确的值
              // var nextRadian=360-Math.acos(cosValue)/(2*Math.PI/360);
              Contant.startRadian=360-Math.acos(cosValue)/(2*Math.PI/360);
              Contant.startRadian=parseFloat(Contant.startRadian.toFixed(2));//保存两位小数
            }else{//落点在圆心的右边，形成的角是正确的值，不用减去
              // var nextRadian=Math.acos(cosValue)/(2*Math.PI/360);
              Contant.startRadian=Math.acos(cosValue)/(2*Math.PI/360);
              Contant.startRadian=parseFloat(Contant.startRadian.toFixed(2));//保存两位小数
            }
            // var lastThisHubCenterY=thisHub.centerY;
            //开始做圆周运动以后，把障碍物下移
            var moveDistance=thisHub.centerY-r.y;//求出下移的距离
            var moveNum=moveDistance/winH*count;
            moveNum=Math.abs(Math.round(moveNum));//求出下移的个数
            // moveDownIsStop=false;
            point+=moveNum;//累加分数
            moveDown(moveNum);//下移动画
          }
        }
        x3=parseFloat(x3.toFixed(2));
        drawCircle(x3,y3,skyBoat.r,'fill');//重新绘制飞船的坐标
        drawMap(AllXY);//绘制障碍物
      },5);

    }
    function getRandomX(){//获取到随机x坐标
      return Math.round(Math.random()*(winW-70)+40);
    }
    function circlePath(centerX,centerY,skyBoat,radian){//使飞船做圆周运动

      clearInterval(circleStop);//做运动的时候停止直线运动
      console.log("开始做圆周运动");
      circlePathIsStop=false;//记录状态是否停止
      thisHub.centerX=centerX;//保存当前飞船围绕的中心坐标X
      thisHub.centerY=centerY;//保存当前飞船围绕的中心坐标Y
      // var updataText=1;
      if(!radian){
        var i=0;
      }else{
        var i=radian;
      }
      clearInterval(circleStop);
      circleStop=setInterval(function(){
        i++;
        if(i>=360)i=0;
          var radian=(2*Math.PI/360)*i;
          radian=parseFloat(radian.toFixed(2));
          skyBoat.x=parseFloat((centerX+Math.sin(radian)*barrier.r).toFixed(2));
          skyBoat.y=parseFloat((centerY-Math.cos(radian)*barrier.r).toFixed(2));
          clearCircle(centerX,centerY,skyBoat.r);//清除运动物体的位置
          drawCircle(skyBoat.x,skyBoat.y,skyBoat.r,"fill");//绘制运动的物体
          drawCircle(centerX,centerY,barrier.r,"stroke");//绘制一个被围绕题
        },10);
      }
    function clearCircle(x,y,r){//清除圆
      var br = barrier.r
        context.clearRect(x-br-r,y-br-r,(br*2)+r*2,(br*2)+r*2);
        //算左上角的坐标思路
        //圆心的x-半径-运动的圆的半径=左上角的X
        //圆心的y-半径-运动的圆的半径=左上角的Y
        //直径+运动圆的直径=结束坐标的x
        //直径+运动圆的直径=结束坐标的y
    }
    function drawMap(AllXY){//绘制地图,就是绘制AllXY数组的所有坐标
      for (var i = 0; i < AllXY.length/2; i++) {
        drawCircle(AllXY[i*2],AllXY[i*2+1],barrier.r,"stroke");
      }
    }
    function gety3(x1,y1,x2,y2,x3){//根据直线方程推导出来的直线路线
      // return (y2-y1)*((x3-x1)/(x2-x1))+y1
      var y3=(y2-y1)*((x3-x1)/(x2-x1))+y1;
      // console.log("y轴的坐标保留两位小数点"+y3)
      return parseFloat(y3.toFixed(2));
    }
    function getx3(x1,y1,x2,y2,y3){//根据直线方程推导出来的直线路线
      // return (y2-y1)*((x3-x1)/(x2-x1))+y1
      var x3=(x2-x1)*((y3-y1)/(y2-y1))+x1
      return parseFloat(x3.toFixed(2));
    }
    function isContact(AllXY,x,y){//判断是否碰撞
      //传入含有所有障碍物的坐标数组AllXY和飞船的坐标x,y
      //返回值false表示和障碍物碰撞
      var AllXYCopy=[];//设置一个数组来承载筛选过的数组,因为当前的飞船正在围绕一个障碍物做圆周运动，所以要去除当前的障碍物的坐标
      for(var copy=0;copy<AllXY.length/2;copy++){
        if(AllXY[copy*2]!=thisHub.centerX){//
          AllXYCopy.push(AllXY[copy*2]);
        }
        if(AllXY[copy*2+1]!=thisHub.centerY){
          AllXYCopy.push(AllXY[copy*2+1]);
        }
      }
      for(var i=0;i<AllXYCopy.length/2;i++){//
        var Distance=getDistance(AllXYCopy[2*i],AllXYCopy[2*i+1],x,y);//获取每一个障碍物的坐标
         if(Distance<=barrier.r){//每一个障碍物和飞船的距离如果比他们之间最小的距离还小，就判定为碰撞
            Contant={
             x:AllXYCopy[2*i],//获取碰撞障碍物的x坐标
             y:AllXYCopy[2*i+1],//获取碰撞障碍物的y坐标
             result:false,
           }
           return Contant;
         }
      }
    }
    function getDistance(x1,y1,x2,y2){//该函数得出两个坐标之间的距离
      var distance=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
      //通过三角函数可以推导
      return distance;
    }
    function moveDown(num){//使障碍物下移的函数
      AddPoint.innerText=point;
      var offsetBottom=parseInt(winH/count);//一次的下移量
      var stopValue=AllXY[1];//保存第一个y坐标
      var roll=10;//滚动的速度
      moveDownIsStop=true;//记录下移动画的状态
      clearInterval(moveDownStop);//每一次进来都清除定时器
      var moveDownStop=setInterval(function(){
        roll+=1;//累加
        for(var i=0;i<AllXY.length/2;i++){
          if(AllXY[1]>stopValue+offsetBottom*num){//如果第一个y坐标的坐标超过移动的坐标，停止动画
            clearInterval(moveDownStop);//如果达到指定的下移数，清除定时器
            moveDownIsStop=false;//
            var deleteXY=AllXY.splice((-2)*num);//因为元素被下移的看不到的地方，所以要清除元素的坐标，清除的数量是传入的数量的2倍，清除的坐标应该是在数组的后面
            for(var j=num-1;j>=0;j--){//补全数组中因为下移而删除的坐标
              var addX=getRandomX();//获取随机x坐标
              var addY=AllY[j];
              AllXY.unshift(addX,addY)//将坐标添加到数组的前面
            }
            //更新所有的y坐标，因为y坐标的是固定但是经过其他的函数，被改变了，在这个重新矫正y坐标
            for(var updata=0;updata<AllXY.length/2;updata++){
              AllXY[updata*2+1]=AllY[updata];
            }
            drawMap(AllXY);//重新绘制障碍物
            circlePath(Contant.x,thisHub.centerY,skyBoat,Contant.startRadian);//当下移动画结束的时候,开始执行圆周运动
            break;//终止for循环
          }else{//如果没有停止下移动画，那么每次都移动roll/(AllXY.length/2);
                //因为为了与障碍
            skyBoat.y+=roll/(AllXY.length/2);
            AllXY[2*i+1]+=roll;//没有的达到指定的坐标，每一个y坐标不停的加roll;
          }
          // AllXY[2*i+1]+=roll;//没有的达到指定的坐标，每一个y坐标不停的加roll;
        }
        // console.log("是否改变值后"+AllXY);
        context.clearRect(0,0,winW,winH);//清除界面
        drawMap(AllXY);//重新绘制障碍物
        drawCircle(skyBoat.x,skyBoat.y,skyBoat.r,"fill");//更新飞船的位置
      },10);

    }
    function getArrayIndex(arr,inArr){//获取inArr在arr数组中的下标
      for(var i=0;i<arr.length;i++){
        if(arr[i]==inArr){
          return i;
        }
      }
    }
  </script>
</html>
